- get it from Eternal Bliss' The Crackmes page (http://crackmes.cjb.net)
WHAT YOU NEED TO HAVE:
======================
- target program
- SoftIce
- ProcDump
- Hex editor
- any patch producer (optional)
WHAT YOU NEED TO KNOW:
======================
- at least the basics of cracking
- how to redirect the code (memory patching)
- any programming language if you're going to make a keygen (well, not any if you want to
follow the rules completely)
==========
THE ESSAY:
==========
1. INTRODUCTION
===============
This is DAMN Official Contest Crackme. It was coded by tHE EGOiSTE. You had to send your solution till September 10, 1999, if you wanted to get the trial status at DAMN.
The rules are:
- you have to code a keygen
- you have to code a patch for the program so it says it's unlocked:
- in the title bar
- on the big button
- in the message box when the big button is pressed
The executable is compressed and the main goal is to code a patch that doesn't use any loader/process patcher.
Additional rule is that both keygen and patch must be win32 apps. They must not be coded in Visual Basic, Delphi or C++ Builder. Win32Asm or C/C++ using pure API functions are prefered.
Let's begin.
2. NAME/SERIAL COMBINATION
==========================
You have to enter your name and the correct key. We notice that 'Register' button is disabled and it stays disabled when you write, so it's not just a length check or something. It's enabled when the correct key is inserted.
OK, start Softice and Crackme and type in your name and any key. I typed
Name: Matjaz
Key : 1234567
Put a bpx on getdlgitemtexta and type in one more character('8'). SI breaks. Press F12 and trace into a call at 401163.
...
401301 mov edi, 402353 > put address of our name into edi
401306 mov ebx, 44414d4e > put a constant value into ebx
40130b xor edx, edx > clear edx
40130d mov ecx, edx > clear ecx (counter)
40130f xor eax, eax > clear eax
401311 mov al, [ecx+edi] > put the first char of our name in al
401314 add edx, eax > add it to edx
401316 ror ebx, 1 > rotate right
401318 ror ebx, cl > rotate right
40131a xor ebx, edx > obvious
40131c cmp ecx, esi > are we done? (esi is length(name)-1)
40131e jz 401323 > jump if we are
401320 inc ecx > increase counter if not
401321 jmp 40130f > loop (next char)
401323 or ebx, 10101010 > final modification of the result (ebx)
...
As you can see, the algo is very very simple. The ebx register contains the correct key. The rest of the code here is just for checking if the key we entered is correct.
Name: Matjaz
Key : 9D913052
To finish the task, you have to code a keygen. Well, that's easy. Just copy the above code (if you're programming in Win32Asm), correct a few things and it's done.
3. CHANGING THE TITLES
======================
Coding a keygen is just a warm up, it's really way too easy for a trial crackme. So here's the harder part. We must patch the crackme in a way that it always says it's unlocked.
Let's first correct the title bar and the big button. This strings are put there before the form is shown, so we must investigate there.
When we're changing properties of controls, we need to know their handles (Win32Asm knowledge helps here). To get the control's handle, we use api function getdlgitem, so we put a bpx on it. Run the crackme again and SI breaks. Press F12. We see a loadbitmapa api function. It's a function that loads a picture from the executable. We see that the address it loads it from depends on the value of eax register. By changing this value we see that:
- eax=0 shows 'locked' on the big button
- eax=1 shows 'cracked' on the big button and
- eax=2 shows 'unlocked' on the big button
We want the value of eax always to be 2. So we trace the call at 40119d, because this is where the appropriate address is filled. At the end of this call we see some instructions which modify the value of edx (this value is then copied to eax). We change these so the value of edx is always 2. Change the following adresses to:
4013a6 mov edx, 2 > put 2 in edx
4013ab jmp 4013bf > we do not want to modify this value, so we jump
Ok, let's step on. We see that edx is stored into 402313. Later on we see that this value is copied to eax. Disable all breakpoints and press F5. We see that the big button says 'UNLOCKED' and so does the title bar. Let's press the big button. It says the program is LOCKED. So here's another check. Put a bpx on messageboxa and press the big button again. SI breaks, press F12, the message box is show, click OK and you're back in SI. Now look at the code above the messagebox call. There's a test of eax at 4012ae. If eax is 0, we jump at 4012b0 to 4012ba. Otherwise the value of eax is changed to 0, which means that the 'locked' message is always shown. What we need to do is change that JZ to unconditional JMP. Do that and try again. The problem is solved.
The program now runs at it should, but we can't make this changes directly to EXE because it is compressed. So we need to make a memory patch (if you're not familiar with memory patching, go to http://procdump32.cjb.net. There are a few tutorial on pathing packed files).
We need to break at the beginning of the crackme. If you load it into Symbol Loader, you'll find out that it doesn't break but just runs. So we need to take another way.
Run ProcDump. Choose 'PE Editor' and load damn_contest.exe. You see that the entry point is at 11000. Choose 'Sections' and search for the value that is close to 11000. You'll find out that .DAMN is exactly at 11000. Its raw offset is 6600h. This is the offset we're loking for.
Take your favorite hex editor and load damn_contest.exe. Goto offset 6600 (hex!). You see the value at this offset is 60. Change it to 'cc'. This is the op code for int 3. Then find a place filled with zeros and enter 'some text' there. Save the file. Go into SI and put a bpint 3. Start the crackme. SI breaks. We need to undo the change we made, so type 'e eip 60'. Now we're at the begining and we can trace on. We step till 411559. This is the end of the unpacking routine. All code has been unpacked and now we can do a memory patch.
But where should we put our patching routine? We do a search for 'some text'. The text isn't found. That means that is has been decrypted, unpacked or the hole thing is somehow protected. So the usual way of doing a memory patch is not possible. What now?
While I was cracking this crackme, I tried to put an int 3 to some other places. I got this message that sad: Damn, I can't load. This is the same text we see if we look at the file in hex editor. That means that this text isn't altered by the program itself. And since we're going to do a correct crack, there will be no need to display this message, so we can use this place tu put our patching code.
OK, run the crackme again and find the text: Damn, I ... Put here the instructions needed to patch the memory (you should have written them down before).
Step until 411559. This is where we have to make a jump to our patch routine. So put here:
jmp 411732 (e9d4010000)
Now we need to put the op codes (in the braces) to EXE. Start hex editor and search for the original op codes and replace then with new one (the one in braces). Run the crackme again. SI breaks. Do a 'e eip 60' again and step on. Step until 411559. There should be
jmp 411732 (e940010000)
but it's not! Why? Because this part of program has been changed since it was run, although it is a part of decompressing routine. Looks like there's another routine before the decompressing one. It's main part is at 411098-4110b5. By tracing this addresses we see that they overwrite the addresses till 411564, that is the RET instruction. What we can do here is we can shorten this routine so it doesn't proceed till the end (411564), but until 411559 (actually 411557, because the loop changes 4 bytes at the time). We change another few bytes with directly changing them in the EXE since they will not be overwritten (because we shortened the routine).
This may be a little confusing, but that's just the way it is. We see that the call at 411098 returns 49a. This is the number that tells how many times the next loop will be executed. By trying we find out that the number should be 48c, so the routine changes bytes just till 411557. So we need to change the instructions as follows:
41109d mov eax, 48c (b98c040000)
4110a2 lea edi, [ebp+444acf] (8dbdcf4a4400)
4110a8 mov esi, [ebp+4450b5] (8bb5b5504400)
4110ae sar ecx, 2 (c1f902)
4110b1 repz movsd (f3a5)
4110b3 nop (90)
4110b4 nop (90)
4110b5 nop (90)
4110b6 nop (90)
As you see, we have overwritten the second part of this routine (the other repz), since we will enter this codes manually in the EXE.
Now we're almost finished. We open the crackme in hex editor once more and put in the op codes from the above part of the program (by searching for the original codes).
The only thing left to do is enter the codes that are missing because we shortened the routine. This codes are (look at 411557 in SI):
1c61e9b9fbffff9090c20c0050c3
You should do a search for 98e3b92027571d (the original bytes) and then place them there where this string is found. Save the file, disable all breakpoints and run the crackme. If you've done everything right, the program runs without error and with UNLOCKED titles.
That's it. You now have a cracked EXE. The job is practicly done. You can now write a patch executable that will change the original EXE to cracked one. Several patch produces are available that compare the original and the cracked file and produce a nice patch (Patch Producer, Cogen II ...), but if you wanna play by the rules, you have to code you own. You can still use a file-compare utility.
Including in this package you should find keygen.exe and patch.exe.
I hope you've learned something from this tutorial. You will probobly have to read it a few more times to completely understand it. If you have any question, comment or you have an idea of how to crack this simplier, feel free to mail me.